package com.xiaozhi.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.xiaozhi.common.context.UserTokenContextHolder;
import com.xiaozhi.common.web.AjaxResult;
import com.xiaozhi.dto.UserDTO;
import com.xiaozhi.entity.SysDevice;
import com.xiaozhi.entity.SysUser;
import com.xiaozhi.request.UserLoginReqVO;
import com.xiaozhi.response.UserLoginRespVO;
import com.xiaozhi.service.SysUserService;
import com.xiaozhi.service.WxUserService;
import com.xiaozhi.utils.JsonUtil;
import com.xiaozhi.vo.UserTokenVO;


import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import reactor.core.publisher.Mono;

import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.bind.annotation.RequestParam;


/**
 * 微信小程序用户接口
 *
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/wx/user")
public class WxMaUserController {
    private final WxMaService wxMaService;
    private final SysUserService sysUserService;
    private final WxUserService wxUserService;

    /**
     * 登陆接口
     */
    @GetMapping("/login")
    public Mono<AjaxResult> login( String code,ServerWebExchange exchange) {
        if (StringUtils.isBlank(code)) {
          
            AjaxResult result = AjaxResult.error();
            result.put("data", "empty jscode");
            return Mono.just(result);
        }
        //if (!wxMaService.switchover(appid)) {
        //    throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        //}

        try {
           
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
            log.info(session.getSessionKey());
            log.info(session.getOpenid());
            String sessionKey = session.getSessionKey();
            String openId = session.getOpenid();
            //TODO 可以增加自己的逻辑，关联业务相关数据
            SysUser user = sysUserService.getOne(openId);
            boolean bool = false;
            String token = IdUtil.fastSimpleUUID() + RandomUtil.randomString(8);
            if (null != user) {
                //存在，
                //user.setAvatarUrl(StrUtil.isNotBlank(userLoginDTO.getAvatarUrl()) ? userLoginDTO.getAvatarUrl()
                //        : user.getAvatarUrl());
                //user.setGender(Objects.nonNull(userLoginDTO.getGender()) ? userLoginDTO.getGender() : user.getGender());
                //user.setNickName(
                //        StrUtil.isNotBlank(userLoginDTO.getNickName()) ? userLoginDTO.getNickName() : user.getNickName());
            } else {
                bool = true;
                user = new SysUser();
                //user = new User();
                //BeanUtil.copyProperties(userLoginDTO, user, false);
            }
    
            //if (StrUtil.isNotBlank(user.getNickName())) {
            //    user.setNickName(user.getNickName().trim());
            //}
            user.setCreateTime(new Date());
            UserTokenVO userTokenVO = new UserTokenVO();
            if (bool) {
                //新增
                user.setOpenId(openId);
                //user.setUserId(2);
                user.setToken(token);
                user.setUsername("defalut10");
                user.setPassword("123456");
                sysUserService.add(user);
                //UserTokenVO userTokenVO = new UserTokenVO();
                BeanUtil.copyProperties(user,userTokenVO);
                wxUserService.addUserTokenVO(userTokenVO);
               //userService.save(user);
            } else {
                //更新登录信息
                user.setToken(token);
                sysUserService.updateToken(user);
                BeanUtil.copyProperties(user,userTokenVO);
                userTokenVO.setToken(token);
                wxUserService.update(userTokenVO);
                //userService.updateById(user);
            }
            Map<String,String> resp = new java.util.HashMap<>();;
            resp.put("openid",openId);
            resp.put("token", token);
            AjaxResult result = AjaxResult.success();
            result.put("data", resp);
            return Mono.just(result);
        }
          catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            AjaxResult result = AjaxResult.error();
            result.put("data", e.toString());
            return Mono.just(result);
       } 
        finally {
            //WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @GetMapping("/info")
    public String info( 
                       String signature, String rawData, String encryptedData, String iv) {
        //if (!wxMaService.switchover(appid)) {
        //    throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        //}
        String sessionKey = "";//sysUserService.generateCode(null);
        // 用户信息校验
        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            WxMaConfigHolder.remove();//清理ThreadLocal
            return "user check failed";
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
        WxMaConfigHolder.remove();//清理ThreadLocal
        return JsonUtil.toJson(userInfo);
    }
    @GetMapping("/userinfo")
    public Mono<AjaxResult> userInfo(ServerWebExchange exchange){
        try {
            String token = UserTokenContextHolder.GetUserTokenFromWebExchange(exchange);
            UserTokenVO user = wxUserService.getUserFromToken(token);
            String openId = user.getOpenId();
            
            SysUser sysuser = sysUserService.selectUserByOpenId(openId);
            AjaxResult result = AjaxResult.success();
            result.put("data", sysuser);
            return Mono.just(result);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Mono.just(AjaxResult.error());
        }
    }

    /**
     * 用户信息修改
     *
     * @param user
     * @return
     */
    @PostMapping("/update")
    public Mono<AjaxResult> update(@RequestBody SysUser user,ServerWebExchange exchange) {
        try {
            log.info("username:"+user.getUsername());
            log.info("nickname:"+user.getNickName());
            String token = UserTokenContextHolder.GetUserTokenFromWebExchange(exchange);;
            UserTokenVO user1 = wxUserService.getUserFromToken(token);
            String openId = user1.getOpenId();
            //SysUser userQuery = new SysUser();

            SysUser userQuery = sysUserService.selectUserByOpenId(openId);
            if (ObjectUtils.isEmpty(userQuery)) {
                return Mono.just(AjaxResult.error("无此用户，操作失败"));
            }
            userQuery.setName(user.getName());
            userQuery.setUsername(user.getUsername());
            userQuery.setNickName(user.getNickName());
            userQuery.setAvatar(user.getAvatar());
            userQuery.setAvatarUrl(user.getAvatarUrl());
            userQuery.setState(user.getState());
            userQuery.setTel(user.getTel());
            userQuery.setEmail(user.getEmail());

            //BeanUtil::copyProperties(user,userQuery);

            if (0 < sysUserService.update(userQuery)) {
                return Mono.just(AjaxResult.success());
            }
            return Mono.just(AjaxResult.error());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Mono.just(AjaxResult.error());
        }
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @GetMapping("/phone")
    public String phone(@PathVariable String appid, String sessionKey, String signature,
                        String rawData, String encryptedData, String iv) {
        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }

        // 用户信息校验
        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            WxMaConfigHolder.remove();//清理ThreadLocal
            return "user check failed";
        }

        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
        WxMaConfigHolder.remove();//清理ThreadLocal
        return JsonUtil.toJson(phoneNoInfo);
    }

}
